package team.seekers.hula.auth.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import team.seekers.hula.auth.dao.PermissionDao;
import team.seekers.hula.auth.entity.dao.PermissionDO;
import team.seekers.hula.auth.entity.dto.PermissionDTO;
import team.seekers.hula.common.utils.BaseConvertUtils;
import team.seekers.hula.common.utils.RedisConstants;

import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AuthService {
    @Autowired
    private PermissionDao permissionDao;

    private static final Pattern REGEX_PATH_VARIABLE = Pattern.compile("\\{.*?\\}");

    /**
     * 同步微服务 URL 到权限中心
     **/
    public void syncNewPermissionUrl(List<PermissionDTO> permissionDTOList) {
        List<PermissionDO> permissionDOList = PermissionDO.from(permissionDTOList);
        List<String> urlList = permissionDOList.stream().map(PermissionDO::getUrl).collect(Collectors.toList());
        List<PermissionDO> dbUrlList = permissionDao.lambdaQuery().select(PermissionDO::getUrl).in(PermissionDO::getUrl, urlList).list();
        Set<String> dbUrlSet = dbUrlList.stream().map(PermissionDO::getUrl).collect(Collectors.toSet());
        permissionDOList = permissionDOList.stream().filter(permissionDO -> !dbUrlSet.contains(permissionDO.getUrl())).collect(Collectors.toList());
        permissionDOList.forEach(permissionDO -> permissionDO.setRoles(null));
        permissionDao.saveBatch(permissionDOList);
    }

    /**
     * 查询所有url权限信息
     **/
    @Cacheable(value = RedisConstants.ALL_URL_PERMISSION)
    public List<PermissionDTO> listAll() {
        List<PermissionDO> permissionDOList = permissionDao.list();
        return PermissionDO.to(permissionDOList);
    }

//    @Cacheable(key = "#url", value = RedisConstants.URL_TO_ROLES)
    public List<String> urlToRoles(String url) {
        PermissionDO permissionDO = permissionDao.lambdaQuery().select(PermissionDO::getRoles).eq(PermissionDO::getUrl, url).one();
        // 查询使用了 PathVariable 的 URL
        if (permissionDO == null) {
            permissionDO = permissionDao.list().stream()
                    .filter(p -> p.getUrl().indexOf('{') != -1 && p.getUrl().indexOf('}') != -1)
                    .filter(p -> url.matches(REGEX_PATH_VARIABLE.matcher(p.getUrl()).replaceAll(".*?")))
                    .findFirst().orElse(null);
        }
        return BaseConvertUtils.stringToList(Optional.ofNullable(permissionDO).orElse(new PermissionDO()).getRoles());
    }
}
